package org.swingDemo.UI.panel;

import net.miginfocom.swing.MigLayout;
import org.swingDemo.UI.MainFrame;
import org.swingDemo.util.IconUtil;
import org.swingDemo.util.UIUtil;
import org.swingDemo.worker.MoveFileWorker;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class ImageOperatePanel extends JPanel implements KeyListener, ComponentListener {

    private ImagePanel imagePanel;
    private JLabel orderLabel;
    private JButton previousButton;
    private JButton nextButton;
    private ButtonGroup radioButtonGroup;
    private List<JRadioButton> classifyRadioButtonList = new ArrayList<>();
    private JTextField classifyTextField;
    private JButton addClassifyButton;
    private JButton clearClassifyButton;

    private JPanel radioPanel;

    private List<String> classifyList = new ArrayList<>();

    private File file;
    private List<File> fileList;

    public ImageOperatePanel() {
        initPanel();
        this.addComponentListener(this);
        this.addKeyListener(this);
    }

    private void initPanel() {
        imagePanel = new ImagePanel();
        imagePanel.addKeyListener(this);
        orderLabel = UIUtil.createLabel("");
        previousButton = UIUtil.createButton("上一个", IconUtil.PreviousIcon, e -> {
            previousImage();
        });
        nextButton = UIUtil.createButton("下一个", IconUtil.NextIcon, e -> {
            nextImage();
        });

        JPanel centerPanel = new JPanel(new MigLayout("fill",
                "[fill]", "[fill][][]"));
        centerPanel.add(imagePanel, "push, wrap");
        centerPanel.add(orderLabel, "wrap");
        centerPanel.add(previousButton, "split 2,alignx right");
        centerPanel.add(nextButton);

        JPanel classifyPanel = initClassifyPanel();

        this.setLayout(new BorderLayout());
        this.add(centerPanel, BorderLayout.CENTER);
        this.add(classifyPanel, BorderLayout.PAGE_END);
    }

    private JPanel initClassifyPanel() {
        radioButtonGroup = new ButtonGroup();
        classifyTextField = UIUtil.createTextField("", true);
        addClassifyButton = UIUtil.createButton("添加分类", null, e -> {
            addClassify();
        });
        clearClassifyButton = UIUtil.createButton("清空分类", null, e -> {
            clearClassify();
        });

        radioPanel = new JPanel(new MigLayout());

        JPanel addClassifyPanel = new JPanel(new MigLayout("fill", "[fill][][]"));
        addClassifyPanel.add(classifyTextField, "push");
        addClassifyPanel.add(addClassifyButton);
        addClassifyPanel.add(clearClassifyButton);

        JPanel panel = new JPanel(new BorderLayout());
        panel.add(radioPanel, BorderLayout.CENTER);
        panel.add(addClassifyPanel, BorderLayout.PAGE_END);
        return panel;
    }

    private void addClassify() {
        String classifyName = classifyTextField.getText();
        if (classifyList.contains(classifyName)) {
            JOptionPane.showMessageDialog(MainFrame.mainFrame, "分类已存在...");
            return;
        }
        classifyList.add(classifyName);
        redrawRadioButtons();
    }

    private void clearClassify() {
        classifyList.clear();
        redrawRadioButtons();
    }

    private void redrawRadioButtons() {
        radioPanel.removeAll();
        classifyRadioButtonList.clear();
        radioButtonGroup.clearSelection();
        for (String classifyName : classifyList) {
            JRadioButton radioButton = UIUtil.createRadioButton(classifyName, radioButtonGroup);
            classifyRadioButtonList.add(radioButton);
            radioButton.addActionListener(e -> {
                moveFile(radioButton.getText());
            });
            radioPanel.add(radioButton);
        }
        this.updateUI();
    }

    private void clearRadioButtonState() {
        radioButtonGroup.clearSelection();
        for (JRadioButton radioButton : classifyRadioButtonList) {
            radioButton.setSelected(false);
        }
    }

    private void moveFile(String folderName) {
        final File file = this.file;
        MoveFileWorker worker = new MoveFileWorker(file, folderName);
        worker.execute();
        nextImage();
        this.fileList.remove(file);
        updateOrderLabelText();
    }

    private void previousImage() {
        int index = fileList.indexOf(file);
        if (index == -1) {
            this.file = null;
        } else {
            index = (index == 0) ? fileList.size() - 1 : index - 1;
            this.file = fileList.get(index);
        }
        updateCurrentFile();
    }

    private void nextImage() {
        int index = fileList.indexOf(file);
        if (index == -1) {
            this.file = null;
        } else {
            index = (index == fileList.size() - 1) ? 0 : index + 1;
            this.file = fileList.get(index);
        }
        updateCurrentFile();
    }

    public void operateFile(File file, List<File> fileList) {
        if (file == null || fileList.isEmpty()) {
            return;
        }
        this.file = file;
        this.fileList = fileList;
        updateCurrentFile();

        // 获取文件所在目录内的文件夹，用于创建分类选项
        classifyList.clear();
        final File[] files = file.getParentFile().listFiles(subFile -> subFile.isDirectory());
        for (File subFile : files) {
            classifyList.add(subFile.getName());
        }
        redrawRadioButtons();
        clearRadioButtonState();
    }

    private void updateCurrentFile() {
        imagePanel.updateImage(this.file);
        updateOrderLabelText();
        clearRadioButtonState();
    }

    private void updateOrderLabelText() {
        int index = fileList.indexOf(file);
        String text = (new StringBuilder()).append(index + 1).append(" / ").append(fileList.size()).toString();
        orderLabel.setText(text);
    }

    @Override
    public void keyPressed(KeyEvent e) {
        final int keyCode = e.getKeyCode();
        if (keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_UP) {
            previousImage();
        } else if (keyCode == KeyEvent.VK_RIGHT || keyCode == KeyEvent.VK_DOWN) {
            nextImage();
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    @Override
    public void componentShown(ComponentEvent e) {
        this.requestFocus();
    }

    @Override
    public void computeVisibleRect(Rectangle visibleRect) {
        super.computeVisibleRect(visibleRect);
    }

    @Override
    public void componentHidden(ComponentEvent e) {

    }

    @Override
    public void componentMoved(ComponentEvent e) {

    }

    @Override
    public void componentResized(ComponentEvent e) {

    }
}
